cmake_minimum_required(VERSION 3.10)
project(starship_proto_generator)

# 查找Protobuf包（只用于获取protoc路径）
# 查找Protobuf包
# 首先尝试简化查找过程，仅关注我们真正需要的protoc
find_package(Protobuf QUIET)

# 如果没有找到，或者库文件路径不完整，设置明确的路径
if(NOT Protobuf_FOUND OR NOT Protobuf_LIBRARIES)
    message(WARNING "自动查找Protobuf失败或缺少库文件，使用强制设置...")
    # 直接设置protoc可执行文件和必要路径
    set(Protobuf_FOUND TRUE)
    set(Protobuf_PROTOC_EXECUTABLE "/usr/local/bin/protoc" CACHE FILEPATH "protoc编译器路径" FORCE)
    set(Protobuf_INCLUDE_DIRS "/usr/include" CACHE PATH "Protobuf头文件路径" FORCE)
    # 尝试设置库文件的具体路径
    set(Protobuf_LIBRARY_DEBUG "" CACHE FILEPATH "Debug Protobuf库" FORCE)
    set(Protobuf_LIBRARY_RELEASE "" CACHE FILEPATH "Release Protobuf库" FORCE)
    set(Protobuf_LIBRARIES protobuf CACHE STRING "Protobuf库名称" FORCE)
endif()

# 备用方案：直接设置protoc可执行文件路径（如果find_package仍然失败）
if(NOT Protobuf_FOUND OR NOT Protobuf_LIBRARIES)
    message(WARNING "自动查找Protobuf失败或缺少库文件，尝试使用默认路径...")
    # 您可以根据Docker环境中的实际情况修改下面的路径
    set(Protobuf_PROTOC_EXECUTABLE "/usr/bin/protoc" CACHE FILEPATH "protoc编译器路径")
    set(Protobuf_INCLUDE_DIRS "/usr/include" CACHE PATH "Protobuf头文件路径")
    set(Protobuf_LIBRARIES "protobuf" CACHE STRING "Protobuf库名称")
endif()


# 显示Protobuf信息
message(STATUS "Protobuf compiler: ${Protobuf_PROTOC_EXECUTABLE}")
message(STATUS "Protobuf include directories: ${Protobuf_INCLUDE_DIRS}")
message(STATUS "Protobuf libraries: ${Protobuf_LIBRARIES}")

# 获取所有.proto文件
file(GLOB_RECURSE PROTO_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/proto_def ${CMAKE_CURRENT_SOURCE_DIR}/proto_def/*.proto)

# 设置输出目录
set(PROTOBUF_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/)
set(PROTOBUF_INPUT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/proto_def)

# 创建输出目录
file(MAKE_DIRECTORY ${PROTOBUF_OUTPUT_DIR})

# 用于存储所有生成的源文件
set(ALL_PROTO_SRCS "")
set(ALL_PROTO_HDRS "")

# 为每个.proto文件生成.pb.cc和.pb.h文件
foreach(REL_PROTO_FILE ${PROTO_FILES})
    # 替换.proto扩展名为.pb.cc
    string(REPLACE ".proto" ".pb.cc" CC_FILE "${REL_PROTO_FILE}")
    string(REPLACE ".proto" ".pb.h"  H_FILE "${REL_PROTO_FILE}")
    
    # 设置输出文件路径
    set(CC_OUTPUT "${PROTOBUF_OUTPUT_DIR}/${CC_FILE}")
    set(H_OUTPUT  "${PROTOBUF_OUTPUT_DIR}/${H_FILE}")
    
    # 获取完整.proto文件路径
    set(PROTO_FILE "${PROTOBUF_INPUT_DIR}/${REL_PROTO_FILE}")
    
    # 获取目录名并创建
    get_filename_component(CC_DIR ${CC_OUTPUT} DIRECTORY)
    file(MAKE_DIRECTORY ${CC_DIR})
    
    # 添加自定义命令来生成源文件
    add_custom_command(
        OUTPUT ${CC_OUTPUT} ${H_OUTPUT}
        COMMAND ${Protobuf_PROTOC_EXECUTABLE}
        ARGS --cpp_out=${PROTOBUF_OUTPUT_DIR}
             -I${PROTOBUF_INPUT_DIR}
             ${REL_PROTO_FILE}
        DEPENDS ${PROTO_FILE}
        COMMENT "Generating ${CC_FILE} and ${H_FILE}"
        VERBATIM
    )
    
    # 添加到源文件列表
    list(APPEND ALL_PROTO_SRCS ${CC_OUTPUT})
    list(APPEND ALL_PROTO_HDRS ${H_OUTPUT})
endforeach()

# 创建一个自定义目标来生成所有protobuf文件
add_custom_target(generate_all_proto ALL
    DEPENDS ${ALL_PROTO_SRCS} ${ALL_PROTO_HDRS}
    COMMENT "Generating all protobuf files"
)

# 添加安装目标（可选）
install(DIRECTORY ${PROTOBUF_OUTPUT_DIR} 
        DESTINATION generated 
        USE_SOURCE_PERMISSIONS
        FILES_MATCHING PATTERN "*.pb.*")

message(STATUS "Protobuf files will be protos in: ${PROTOBUF_OUTPUT_DIR}")
message(STATUS "Use 'cmake --build .' to generate the .pb.cc/.pb.h files")